package com.sky.aspect;

import com.sky.anno.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Slf4j
@Component
@Aspect
public class AutoFillAspect {
    //创建通知方法
    @Before("@annotation(com.sky.anno.AutoFill)")//通知方式设置为前置通知注解方式(括号里写注解的全限定名)
    public void AutoFill(JoinPoint joinPoint) {
        //获取目标方法对象
        MethodSignature methodExecution=(MethodSignature) joinPoint.getSignature();//getSignature()获取方法签名,再强转成方法签名
        Method method=methodExecution.getMethod();//获取方法
        //获取目标方法中的参数
        Object[] args=joinPoint.getArgs();
        Object entity=0;
        if (args != null & args.length > 0) {
            entity=args[0];
        }
        //对参数进行判断处理
        AutoFill autoFill=method.getAnnotation(AutoFill.class);//获取注解的实例
        OperationType operationType=autoFill.value();//通过实例获取属性值

        try {
            if (operationType.equals(OperationType.INSERT)) {
                //代表是新增方法
                log.info("公共字段填充[insert]");
                Method setUpdateTime=entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                Method setCreateTime=entity.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
                Method setUpdateUser=entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);
                Method setCreateUser=entity.getClass().getDeclaredMethod("setCreateUser", Long.class);
                //调动方法进行字段填充
                setUpdateTime.invoke(entity, LocalDateTime.now());
                setCreateTime.invoke(entity, LocalDateTime.now());
                setUpdateUser.invoke(entity, BaseContext.getCurrentId());
                setCreateUser.invoke(entity, BaseContext.getCurrentId());
            } else {
                //代表是修改方法
                Method setUpdateTime=entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                Method setUpdateUser=entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);
                setUpdateTime.invoke(entity, LocalDateTime.now());
                setUpdateUser.invoke(entity, BaseContext.getCurrentId());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


    }
}
